본문으로 건너뛰기

RBI Proxy 소개

SOFTCAMP SHIELDGate 격리 브라우저 연동을 위한 HTTP/HTTPS 프록시 서비스


📋 목차​

  1. 개요
  2. RBIProxy란?
  3. 전체 아키텍처
  4. 주요 구성 요소
  5. 동작 원리
  6. PAC 파일 설정
  7. 보안 메커니즘
  8. REST API
  9. 기술 스택
  10. 사용 사례

개요​

RBIProxy는 사용자의 일반 브라우저 트래픽을 SOFTCAMP SHIELDGate 격리 브라우저로 자동 연결하는 중간 프록시 서버입니다.

사용자는 평소처럼 웹 브라우징을 하지만, 모든 웹 접속이 격리된 환경(RBI)에서 실행되어 보안 위협으로부터 안전하게 보호됩니다.

핵심 가치​

  • 투명한 보안: 사용자 경험을 해치지 않으면서 보안 강화 (자동 리다이렉트)
  • 중앙 집중식 제어: 단일 프록시로 모든 웹 트래픽을 중앙에서 통제
  • 간단한 중계 구조: URL 변환 및 SHIELDGate 연동만 수행 (복잡한 정책은 SHIELDGate에서 처리)

RBIProxy란?​

RBI (Remote Browser Isolation)​

원격 브라우저 격리 기술은 사용자의 웹 브라우징을 물리적으로 격리된 원격 환경에서 실행하는 보안 솔루션입니다.

전통적인 웹 접속:
[사용자 PC] ──→ [인터넷 웹사이트]
↑
악성코드 다운로드 위험
제로데이 공격 노출
피싱 사이트 직접 접속

RBI 적용 후:
[사용자 PC] ──→ [격리된 브라우저] ──→ [인터넷 웹사이트]
↑
악성코드가 격리 환경에서만 실행
사용자 PC는 안전

RBIProxy의 역할​

RBIProxy는 PAC 필터링을 통과한 트래픽을 SHIELDGate로 변환하는 중계기입니다:

🎯 필터링 구조​

┌──────────────────────────────────────────────────────────────┐
│ PAC 파일 (사용자 PC에서 실행) │
│ "어느 사이트는 프록시 거치고, 어느 건 직접?" │
└────────────┬─────────────────────────────┬───────────────────┘
↓ ↓
[허용 사이트] [차단 사이트]
naver.com example.com
microsoft.com unknown-site.com
내부 IP (192.168.x.x) 기타 모든 사이트
↓ ↓
DIRECT (프록시 안 거침) PROXY 10.14.10.176:9999
↓ ↓
[직접 접속] ┌─────────────────────────────┐
│ RBIProxy 서버 │
│ "URL 변환기" │
└──────┬──────────────────────┘
↓
URL 변환 수행
↓
https://shieldgate.softcamp.co.kr/
gate-proxy?currentTab=true&url=원본URL
↓
HTML 리다이렉트 응답
↓
┌───────────────────────┐
│ 사용자 브라우저가 │
│ 자동으로 이동 │
└──────┬────────────────┘
↓
┌─────────────────┐
│ SHIELDGate │
│ gate-proxy │
└──────┬──────────┘
↓
┌─────────────────┐
│ rb-app │
│ (격리 브라우저) │
└──────┬──────────┘
↓
[실제 웹사이트 접속]

구체적인 예시​

예시 1: naver.com 접속 (허용 사이트)

[사용자] naver.com 입력
↓
[PAC 파일] "naver.com? 어? 너 허용이구나!"
↓
[결정] "그럼 너는 DIRECT"
↓
[결과] naver.com에 바로 접속 ✅ (RBIProxy 안 거침)

예시 2: example.com 접속 (차단 대상 사이트)

[사용자] example.com 입력
↓
[PAC 파일] "example.com? 허용 목록에 없네"
↓
[결정] "너는 RBIProxy로 보내"
↓
[RBIProxy] URL 변환
원본: http://example.com
→
변환: https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com
↓
[HTML 리다이렉트 응답]
<meta http-equiv="refresh" content="0;url=변환된URL"/>
↓
[사용자 브라우저] 자동으로 SHIELDGate URL로 이동
↓
[SHIELDGate] gate-proxy가 rb-app(격리 브라우저) 실행
↓
[rb-app] 격리된 환경에서 example.com 접속
↓
[결과] 사용자는 격리 브라우저로 example.com 이용 ✅

전체 아키텍처​

단순화된 흐름도​

┌─────────────────────┐
│ 사용자 PC │
│ (일반 브라우저) │
│ Chrome / Edge 등 │
└──────────┬──────────┘
│
│ ① Windows 프록시 설정 (PAC)
│ - 허용 사이트 → DIRECT
│ - 차단 사이트 → PROXY 10.14.10.176:9999
↓
┌─────────────────────┐
│ RBIProxy 서버 │
│ (이 프로젝트) │
│ - URL 변환만 │
└──────────┬──────────┘
│
│ ② HTML 리다이렉트
│ shieldgate.softcamp.co.kr/
│ gate-proxy?currentTab=true&url=원본URL
↓
┌─────────────────────┐
│ SHIELDGate │
│ (격리 브라우저) │
│ - gate-proxy │
└──────────┬──────────┘
│
│ ③ rb-app 실행
↓
┌─────────────────────┐
│ rb-app │
│ (격리 브라우저) │
└──────────┬──────────┘
│
│ ④ 실제 웹사이트 접속
↓
┌─────────────────────┐
│ 인터넷 웹사이트 │
│ example.com 등 │
└─────────────────────┘
       ↓

┌─────────────────────┐
│ 인터넷 웹사이트 │
│ example.com 등 │
└─────────────────────┘

### 상세 데이터 흐름

**중요**: PAC 파일이 1차 필터링을 수행합니다!

┌─────────────────────────────────────────────────────────────────┐
│ 사용자 PC │
│ │
│ [Chrome/Edge] 사용자가 URL 입력 │
│ ↓ │
│ ┌─────────────────────────────────────────────┐ │
│ │ PAC 파일 (필터링) │ │
│ │ "이 사이트 어디로 보낼까?" │ │
│ └──────────┬──────────────────────────────────┘ │
│ │ │
│ ┌──────┴───────┐ │
│ ↓ ↓ │
│ [허용 사이트] [차단 대상] │
│ naver.com example.com │
│ ↓ ↓ │
│ DIRECT PROXY 10.14.10.176:9999 │
│ │
└──────┼──────────────┼──────────────────────────────────────────┘
│ │
↓ │ RBIProxy로 전달
[naver.com] ↓
직접 접속 ┌─────────────────────────────────────────────────────────────────┐
│ RBIProxy 서버 │
│ (URL 변환기) │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 1. 요청 수신 (9999 포트) │ │
│ └──────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────▼───────────────────────────────────────┐ │
│ │ 2. URL 변환 │ │
│ │ 원본: http://example.com │ │
│ │ → │ │
│ │ 변환: https://shieldgate.softcamp.co.kr/ │ │
│ │ gate-proxy?currentTab=true&url=http://example.com│ │
│ └──────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────▼───────────────────────────────────────┐ │
│ │ 3. HTML 리다이렉트 응답 │ │
│ │ │ │
│ └──────────────────┬───────────────────────────────────────┘ │
│ │ │
└─────────────────────┼────────────────────────────────────────────┘
│
↓
┌─────────────────────────────┐
│ 사용자 브라우저가 │
│ 자동으로 SHIELDGate로 이동 │
└─────────────┬───────────────┘
↓
┌─────────────────────┐
│ SHIELDGate │
│ gate-proxy │
└──────────┬──────────┘
│
│ rb-app 실행
↓
┌─────────────────────┐
│ rb-app │
│ (격리 브라우저) │
└──────────┬──────────┘
│
│ 직접 인터넷 접속
↓
┌─────────────────────┐
│ 인터넷 웹사이트 │
│ example.com │
└─────────────────────┘

***

## 주요 구성 요소

### 1. Windows PAC (Proxy Auto-Config)

**위치**: 사용자 PC의 Windows 프록시 설정

**역할**: **1차 필터링 - 사이트별로 프록시 사용 여부 결정**

**중요**: PAC 파일이 먼저 판단합니다!
- ✅ **허용 사이트** (naver.com, microsoft.com 등) → `DIRECT` (프록시 안 거침)
- ⚠️ **일반 사이트** (example.com 등) → `PROXY 10.14.10.176:9999` (RBIProxy로)

**예시 PAC 파일** (`pac.js`):

```javascript
function FindProxyForURL(url, host) \{
// 1. SHIELDGate 자체는 DIRECT (무한 루프 방지)
if (dnsDomainIs(host, "shieldgate.softcamp.co.kr") ||
dnsDomainIs(host, "security365.co.kr")) \{
return "DIRECT";
\}

// 2. 허용 사이트 목록 (예외 처리)
if (dnsDomainIs(host, "naver.com") ||
dnsDomainIs(host, "microsoft.com") ||
dnsDomainIs(host, "office365.com")) \{
return "DIRECT"; // ← naver.com? 어? 너 허용이구나! DIRECT!
\}

// 3. 내부 네트워크는 DIRECT
if (isPlainHostName(host) ||
shExpMatch(host, "*.local") ||
isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")) \{
return "DIRECT";
\}

// 4. 기본 규칙: RBIProxy로 보냄
return "PROXY 10.14.10.176:9999"; // ← example.com? 너는 RBIProxy로!
\}

실제 동작:

사용자가 naver.com 입력
↓
PAC: "naver.com? 어? 너 허용이구나!"
↓
PAC: "그럼 너는 DIRECT"
↓
naver.com에 바로 접속 ✅ (RBIProxy 거치지 않음)


사용자가 example.com 입력
↓
PAC: "example.com? 허용 목록에 없네"
↓
PAC: "너는 RBIProxy로 보내" (PROXY 10.14.10.176:9999)
↓
RBIProxy로 전달 → 다음 단계 진행

PAC 파일 적용 방법:

  1. 수동 적용 (개별 PC):

    • Windows 설정 → 네트워크 및 인터넷 → 프록시
    • "자동 프록시 설정 사용" 활성화
    • 스크립트 주소: http://10.14.10.176:9999/RestAPI/pac.js
  2. GPO 적용 (도메인 일괄 적용):

    그룹 정책 편집기
    → 사용자 구성 → 기본 설정 → Windows 설정 → 레지스트리
    → HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings
    → AutoConfigURL = "http://10.14.10.176:9999/RestAPI/pac.js"
  3. PAC 파일 다운로드:

    # RBIProxy가 제공하는 PAC 파일
    curl http://10.14.10.176:9999/RestAPI/pac.js -o pac.js

2. RBIProxy 서버​

언어: Go (Golang)
포트:

  • 9999: 프록시 서버 (메인 기능)
  • 80: REST API 서버 (관리/모니터링)

배포: Kubernetes (Docker 컨테이너)

주요 역할: "URL 변환기"

PAC에서 보낸 모든 트래픽을 받아서 SHIELDGate URL 형식으로 변환합니다.

┌─────────────────────────────────────────────────────┐
│ RBIProxy 서버 (URL 변환기) │
│ │
│ ① 프록시 요청 수신 (9999 포트) │
│ ↓ │
│ ② URL 변환 │
│ 원본: http://example.com │
│ → │
│ 변환: https://shieldgate.softcamp.co.kr/ │
│ gate-proxy?currentTab=true&url=원본URL │
│ ↓ │
│ ③ HTML 리다이렉트 응답 │
│ <meta http-equiv="refresh" │
│ content="0;url=변환URL"/> │
│ │
└─────────────────────────────────────────────────────┘

핵심 코드 (src/main.go 317~320번 줄):

func redirectUrl(url string) string \{
// SHIELDGate 방식: URL을 쿼리 파라미터로 전달
return cfg.RBIProxy.RBI.BaseURL +
"gate-proxy?currentTab=true&url=" + url
\}

실제 변환 예시:

입력: http://example.com
→
출력: https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com

3. SHIELDGate (격리 브라우저)​

URL: https://shieldgate.softcamp.co.kr

구성:

  • gate-proxy: 웹 인터페이스 (URL을 받아서 rb-app 실행)
  • rb-app: 격리 브라우저 엔진 (실제 웹사이트 접속 및 렌더링)

역할:

  • gate-proxy가 URL 파라미터를 받아서 rb-app(격리 브라우저) 실행
  • rb-app이 격리된 환경에서 실제 웹사이트 렌더링
  • 사용자에게 화면만 스트리밍
  • 보안 정책 적용 (다운로드/업로드/복사 제어 등)

URL 규약:

https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=<원본URL>

동작 방식:

gate-proxy URL로 들어옴
↓
gate-proxy가 url 파라미터 추출
↓
rb-app(격리 브라우저) 실행
↓
rb-app이 실제 웹사이트에 직접 접속
↓
사용자에게 화면 스트리밍

예시:

변환된 URL: https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com
→ gate-proxy가 rb-app 실행
→ rb-app이 http://example.com 접속

동작 원리​

🌟 전체 시나리오: 2가지 경로​

사용자가 웹사이트에 접속할 때 PAC 파일이 먼저 판단합니다:

사용자가 URL 입력
↓
┌───────────────────────────────┐
│ PAC 파일 (1차 필터) │
│ "이 사이트 어디로 보낼까?" │
└───────┬───────────────────────┘
│
┌────┴─────┐
↓ ↓
[허용] [차단]
↓ ↓
DIRECT PROXY
↓ ↓
[끝] [RBIProxy]
↓
[SHIELDGate]

시나리오 A: 허용 사이트 (naver.com)​

PAC에서 끝나는 케이스 - RBIProxy 거치지 않음

Step-by-Step 흐름​

[Step 1] 사용자가 Chrome에 "naver.com" 입력
│
↓
[Step 2] PAC 파일 실행 (사용자 PC에서)
function FindProxyForURL(url, "naver.com") \{
if (dnsDomainIs(host, "naver.com")) \{
return "DIRECT"; // ← 여기서 결정!
\}
\}
│
↓
[Step 3] PAC 판단: "naver.com? 어? 너 허용이구나!"
│
↓
[Step 4] 결정: "그럼 너는 DIRECT" (프록시 사용 안함)
│
↓
[Step 5] naver.com에 직접 접속 ✅

결과: RBIProxy, SHIELDGate 모두 거치지 않음

시나리오 B: 차단 사이트 (example.com)​

RBIProxy + SHIELDGate를 거치는 케이스

Step-by-Step 흐름​

[Step 1] 사용자가 Chrome에 "example.com" 입력
│
↓
[Step 2] PAC 파일 실행 (사용자 PC에서)
function FindProxyForURL(url, "example.com") \{
// 허용 목록에 없음
return "PROXY 10.14.10.176:9999"; // ← 여기서 결정!
\}
│
↓
[Step 3] PAC 판단: "example.com? 허용 목록에 없네"
│
↓
[Step 4] 결정: "너는 RBIProxy로 보내"
│
↓
[Step 5] RBIProxy 수신
→ 프록시 요청 수신 (9999 포트)
│
↓
[Step 6] URL 변환 수행
→ 원본: http://example.com
→ 변환: https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com
│
↓
[Step 7] HTML 리다이렉트 응답 생성
→ <meta http-equiv="refresh" content="0;url=변환URL"/>
→ HTTP 202 Accepted 응답
│
↓
[Step 8] 사용자 브라우저가 자동으로 SHIELDGate URL로 이동
│
↓
[Step 9] SHIELDGate gate-proxy가 URL 파라미터 확인
→ url=http://example.com 추출
│
↓
[Step 10] gate-proxy가 rb-app(격리 브라우저) 실행
│
↓
[Step 11] rb-app이 격리된 환경에서 example.com 직접 접속
│
↓
[Step 12] 웹사이트 렌더링 후 사용자에게 화면 스트리밍
│
↓
[완료] 사용자는 격리 브라우저로 example.com을 안전하게 이용 ✅

시나리오 비교​

단계naver.com (허용)example.com (차단)
PAC 필터DIRECT → 직접 접속PROXY → RBIProxy로
RBIProxy거치지 않음URL 변환 → SHIELDGate로
최종 접속naver.com 직접rb-app(격리 브라우저) 경유
보안 수준일반격리 환경
단계 수5단계12단계

PAC 파일 설정​

PAC 파일이란?​

**PAC (Proxy Auto-Config)**는 JavaScript로 작성된 파일로, 브라우저가 어떤 프록시를 사용할지 동적으로 결정합니다.

RBIProxy용 PAC 파일 작성​

RBIProxy는 /RestAPI/pac.js 엔드포인트를 통해 PAC 파일을 제공합니다.

기본 PAC 파일 구조​

function FindProxyForURL(url, host) \{
// 1. SHIELDGate 자체는 프록시 우회 (무한 루프 방지)
if (dnsDomainIs(host, "shieldgate.softcamp.co.kr") ||
dnsDomainIs(host, "security365.co.kr") ||
dnsDomainIs(host, "softcamp.co.kr")) \{
return "DIRECT";
\}

// 2. 내부 네트워크 (사설 IP) 우회
if (isPlainHostName(host) ||
shExpMatch(host, "*.local") ||
isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")) \{
return "DIRECT";
\}

// 3. 특정 도메인 예외 처리
if (dnsDomainIs(host, "microsoft.com") ||
dnsDomainIs(host, "azure.com") ||
dnsDomainIs(host, "office365.com")) \{
return "DIRECT"; // Microsoft 서비스는 프록시 우회
\}

// 4. 기본 규칙: RBIProxy를 통해 프록시
return "PROXY 10.14.10.176:9999";
\}

PAC 파일 주요 함수​

함수설명예시
dnsDomainIs(host, domain)도메인 일치 확인dnsDomainIs(host, "example.com")
shExpMatch(host, pattern)와일드카드 패턴 매칭shExpMatch(host, "*.google.com")
isInNet(host, network, mask)IP 네트워크 범위 확인isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0")
isPlainHostName(host)호스트명만 있는지 확인 (도메인 없음)isPlainHostName("localhost")

PAC 파일 배포 방법​

방법 1: RBIProxy에서 직접 배포​

RBIProxy는 /RestAPI/pac.js 엔드포인트를 통해 PAC 파일을 제공합니다.

# PAC 파일 접근
http://10.14.10.176:9999/RestAPI/pac.js

Windows 프록시 설정:

  1. 설정 → 네트워크 및 인터넷 → 프록시
  2. "설정 자동 검색" OFF
  3. "설정 스크립트 사용" ON
  4. 스크립트 주소: http://10.14.10.176:9999/RestAPI/pac.js

방법 2: 웹 서버에서 배포​

별도 웹 서버(Apache, Nginx 등)에 PAC 파일을 배포할 수도 있습니다.

# Nginx 설정 예시
location /proxy.pac \{
alias /var/www/html/pac.js;
types \{
application/x-ns-proxy-autoconfig pac;
\}
\}

방법 3: GPO (Group Policy Object) 배포​

Active Directory 환경에서 일괄 적용:

  1. 그룹 정책 관리 콘솔 열기

  2. 새 GPO 생성: "RBIProxy PAC 설정"

  3. 편집 → 사용자 구성 → 기본 설정 → Windows 설정 → 레지스트리

  4. 새 레지스트리 항목:

    Hive: HKEY_CURRENT_USER
    키 경로: Software\Microsoft\Windows\CurrentVersion\Internet Settings
    값 이름: AutoConfigURL
    값 형식: REG_SZ
    값 데이터: http://10.14.10.176:9999/RestAPI/pac.js

PAC 파일 예외 처리 전략​

1. 성능 최적화: 내부 리소스 DIRECT​

// CDN, 정적 리소스는 직접 접속
if (dnsDomainIs(host, "cdn.jsdelivr.net") ||
dnsDomainIs(host, "cdnjs.cloudflare.com")) \{
return "DIRECT";
\}

2. 호환성: 특정 서비스 우회​

// Microsoft 365 서비스는 프록시 우회 (인증 문제 방지)
if (dnsDomainIs(host, "office365.com") ||
dnsDomainIs(host, "sharepoint.com") ||
dnsDomainIs(host, "teams.microsoft.com")) \{
return "DIRECT";
\}

3. 보안: 신뢰 도메인만 RBI 우회​

// 회사 내부 시스템은 DIRECT
if (dnsDomainIs(host, "intranet.company.com") ||
dnsDomainIs(host, "erp.company.com")) \{
return "DIRECT";
\}

PAC 파일 테스트 방법​

// 테스트용 PAC 파일에 디버그 로그 추가
function FindProxyForURL(url, host) \{
var result;

if (dnsDomainIs(host, "shieldgate.softcamp.co.kr")) \{
result = "DIRECT";
\} else if (isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0")) \{
result = "DIRECT";
\} else \{
result = "PROXY 10.14.10.176:9999";
\}

// 브라우저 콘솔에 로그 출력 (디버깅 시에만 사용)
alert("URL: " + url + "\nHost: " + host + "\nResult: " + result);

return result;
\}

온라인 PAC 테스터 활용:

  • PacParser에서 PAC 파일 업로드 후 테스트

보안 메커니즘​

1. TLS MITM (Man-In-The-Middle)​

RBIProxy는 HTTPS 트래픽을 검사하기 위해 MITM 기법을 사용합니다.

동작 과정​

[사용자 브라우저]
│
│ CONNECT example.com:443
↓
[RBIProxy]
│
│ ① HTTP/1.0 200 OK 응답
│ ② example.com용 TLS 인증서 동적 발급
│ ③ 사용자와 TLS 핸드셰이크
│ ④ 암호화된 요청 복호화
│ ⑤ URL 확인: https://example.com/page
│ ⑥ 리다이렉트 응답 생성
↓
[사용자 브라우저]
│
│ 자동으로 SHIELDGate로 이동
↓
[SHIELDGate]

사설 인증서 설치 필수​

HTTPS MITM이 정상 동작하려면 사용자 PC에 RBIProxy의 CA 인증서를 신뢰해야 합니다.

인증서 다운로드:

curl http://10.14.10.176:9999/RestAPI/cert.cer -o rbiproxy_cert.cer

설치 방법:

  1. Windows:

    • rbiproxy_cert.cer 더블클릭
    • "인증서 설치" 클릭
    • "로컬 컴퓨터" 선택
    • "모든 인증서를 다음 저장소에 저장" → 신뢰할 수 있는 루트 인증 기관
    • 설치 완료
  2. GPO 일괄 배포:

    그룹 정책 관리 → 컴퓨터 구성 → Windows 설정 → 보안 설정
    → 공개 키 정책 → 신뢰할 수 있는 루트 인증 기관
    → rbiproxy_cert.cer 추가

2. RBI 연동 방식​

RBIProxy는 두 가지 RBI 연동 방식을 지원합니다:

A. SHIELDGate 방식 (현재 운영 중) ⭐​

설정:

RBI_LINK_TYPE: SHIELDGate

코드 위치: src/main.go 320번 줄

URL 형식:

https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com

처리 방식:

  • RBIProxy는 단순 URL 변환만 수행
  • 원본 URL을 쿼리 파라미터로 전달
  • 보안 정책은 SHIELDGate에서 처리

특징:

  • 단순하고 직관적한 구조
  • URL이 평문으로 노출
  • RBIProxy는 중계기 역할만 수행
  • 정책 관리를 SHIELDGate에 위임

B. DIRECT (JWT) 방식 (현재 미사용)​

설정:

RBI_LINK_TYPE: DIRECT

코드 위치: src/main.go 323~342번 줄

URL 형식:

https://rbi.custom.co.kr/view?url=<JWT_TOKEN>

JWT 토큰 내용 (src/main.go 329~339번 줄에 하드코딩):

\{
"ver": "1.0",
"id": "softcamp.co.kr",
"url": "http://example.com",
"policy": \{
"screenmark": "OFF", // 화면 워터마크
"key": "ON", // 키보드 입력 허용
"site": "ON", // 사이트 접근 허용
"dn": "ON", // 다운로드 허용
"up": "ON", // 업로드 허용
"media": "ON", // 미디어 재생 허용
"menu": "ON", // 메뉴 사용 허용
"clip": "ON" // 클립보드 사용 허용
\},
"exp": 1234567890 // 만료 시간 (12시간 후)
\}

특징:

  • URL이 JWT 토큰으로 암호화
  • 토큰 만료 시간 설정 (12시간)

제약사항:

  • ⚠️ 정책이 코드에 하드코딩되어 있음
  • ⚠️ 모든 요청에 동일한 정책 적용
  • ⚠️ 사용자별/URL별 다른 정책 적용 불가
  • ⚠️ ConfigMap이나 설정 파일로 변경 불가
  • 현재 운영 환경에서는 사용되지 않음

방식 비교 요약​

항목SHIELDGate 방식 (운영 중)DIRECT (JWT) 방식 (미사용)
설정값RBI_LINK_TYPE: SHIELDGateRBI_LINK_TYPE: DIRECT
URL 변환쿼리 파라미터로 평문 전달JWT 토큰으로 암호화
정책 처리SHIELDGate에서 처리JWT 토큰에 포함 (하드코딩)
정책 유연성SHIELDGate에서 유연하게 관리불가능 (코드 수정 필요)
RBIProxy 역할단순 중계기URL + 정책 패키징
현재 사용 여부✅ 사용 중❌ 미사용

왜 SHIELDGate 방식을 사용하는가?​

현재 운영 환경 분석 (ConfigMap 기준):

# build/kube-deploy.yaml
RBI_LINK_TYPE: SHIELDGate # ← 실제 운영 설정
RBI_BASEURL: https://devshieldgate.softcamp.co.kr

SHIELDGate 방식 선택 이유:

  1. 단순성:
    • RBIProxy는 URL 변환만 수행 (src/main.go 320번 줄)
    • 보안 정책 관리를 SHIELDGate에 완전히 위임
    • 코드 수정 없이 SHIELDGate에서 정책 변경 가능
  2. 유지보수성:
    • JWT 방식의 정책은 src/main.go 329~339번 줄에 하드코딩
    • 정책 변경 시 코드 수정 → 빌드 → 배포 필요
    • SHIELDGate 방식은 SHIELDGate 설정만 변경하면 됨
  3. 운영 유연성:
    • 사용자별/그룹별 다른 정책 적용은 SHIELDGate에서 관리
    • RBIProxy는 모든 사용자에게 동일하게 동작
    • 정책 변경에 RBIProxy 재배포 불필요

결론:

  • RBIProxy는 "똑똑한 URL 변환기" 역할에 집중
  • 복잡한 정책 관리는 SHIELDGate의 몫
  • 단순하고 안정적인 아키텍처

3. 무한 루프 방지​

RBIProxy와 SHIELDGate 간의 무한 리다이렉트를 방지하는 메커니즘:

PAC 파일에서 방지:

// SHIELDGate 도메인은 DIRECT로 접속 (프록시 우회)
if (dnsDomainIs(host, "shieldgate.softcamp.co.kr")) \{
return "DIRECT"; // 무한 루프 방지
\}

동작 원리:

사용자가 example.com 입력
↓
PAC: PROXY → RBIProxy로
↓
RBIProxy: shieldgate.softcamp.co.kr/gate-proxy?url=example.com 으로 리다이렉트
↓
사용자 브라우저가 shieldgate.softcamp.co.kr 접속 시도
↓
PAC: "shieldgate.softcamp.co.kr? DIRECT!" ← 여기서 차단!
↓
shieldgate.softcamp.co.kr에 직접 접속 (RBIProxy 안 거침)
↓
무한 루프 방지 ✅

만약 PAC에서 예외 처리하지 않으면:

❌ 무한 루프 발생:
example.com → RBIProxy → shieldgate... → RBIProxy → shieldgate... (반복)

REST API​

RBIProxy는 관리 및 모니터링을 위한 REST API를 제공합니다.

1. 버전 및 헬스체크​

엔드포인트: GET / 또는 GET /ver

curl http://10.14.10.176:9999/ver

응답:

\{
"code": 0,
"msg": "안녕, Hi, こんにちは, 你好, Chào...",
"ver": "1.0.0.5"
\}

용도:

  • 서비스 동작 확인
  • 버전 정보 조회
  • Kubernetes Liveness/Readiness Probe

2. 활성 세션 모니터링​

엔드포인트: GET /sessions

인증:

  • localhost에서 접속 시 인증 불필요
  • 외부 접속 시 Basic Auth 필요
# Basic Auth 사용
curl -u admin:password http://10.14.10.176:9999/sessions

응답:

\{
"code": 0,
"msg": "",
"total": 2,
"sessions": [
\{
"client": "192.168.1.100:48068",
"req": "GET https://example.com",
"time": "295.508µs"
\},
\{
"client": "192.168.1.101:37988",
"req": "CONNECT secure.example.com:443",
"time": "1.381s"
\}
]
\}

용도:

  • 실시간 트래픽 모니터링
  • 성능 분석 (요청 처리 시간)
  • 사용자 접속 추적

3. PAC 파일 배포​

엔드포인트: GET /RestAPI/pac.js

curl http://10.14.10.176:9999/RestAPI/pac.js

응답: JavaScript PAC 파일

용도:

  • 사용자 PC의 프록시 자동 설정
  • 중앙에서 PAC 파일 관리

4. 사설 인증서 배포​

엔드포인트: GET /RestAPI/cert.cer

curl http://10.14.10.176:9999/RestAPI/cert.cer -o rbiproxy_cert.cer

응답: PEM 형식의 CA 인증서

용도:

  • HTTPS MITM을 위한 사설 인증서 배포
  • 사용자 PC에 설치하여 인증서 경고 제거

기술 스택​

언어 및 프레임워크​

기술버전용도
Go (Golang)1.23.11메인 언어
Alpine Linux3.21.3Docker 베이스 이미지
elazarl/goproxy-HTTP/HTTPS 프록시 라이브러리

주요 Go 패키지​

rbiproxy/
├── cert/ # TLS 인증서 동적 발급 (MITM)
├── config/ # 설정 파일 로드 (config.yaml, 환경변수)
├── restapi/ # REST API 서버
│ └── core/ # API 핸들러 (version, sessions)
└── main.go # 프록시 서버 메인 로직

외부 의존성​

  • github.com/elazarl/goproxy: HTTP/HTTPS 프록시 엔진
  • github.com/spf13/viper: 설정 파일 관리
  • dev.azure.com/Security365/go-common:
    • JWT 토큰 생성/검증
    • 로거
    • 유틸리티

빌드 및 배포​

Docker 이미지 빌드:

docker build -t rbiproxy:latest -f build/Dockerfile .

버전 관리:

  • build/version.txt: 메이저.마이너.패치 버전
  • build/version-patch.txt: 패치 번호
  • 빌드 시 자동으로 버전 정보 삽입

사용 사례​

Case 1: 전사 웹 보안 강화​

문제:

  • 직원들이 업무 중 악성 웹사이트 접속
  • 랜섬웨어, 악성코드 다운로드 위험
  • 피싱 사이트 접속으로 인한 계정 탈취

해결:

[모든 직원 PC]
↓ (GPO로 PAC 자동 배포)
[RBIProxy]
↓ (자동 리다이렉트)
[SHIELDGate 격리 브라우저]
↓ (안전한 접속)
[외부 웹사이트]

결과: 악성코드가 격리 환경에서만 실행, 직원 PC는 안전

Case 2: 특정 부서만 RBI 적용​

요구사항:

  • 개발팀은 자유로운 인터넷 사용 필요 (DIRECT)
  • 일반 부서는 RBI를 통한 보안 접속

구현:

// 개발팀 IP 대역
function FindProxyForURL(url, host) \{
var clientIP = myIpAddress();

// 개발팀 IP 대역은 DIRECT
if (isInNet(clientIP, "10.14.20.0", "255.255.255.0")) \{
return "DIRECT";
\}

// 그 외 일반 부서는 RBIProxy 사용
if (/* 예외 조건들 */) \{
return "DIRECT";
\}

return "PROXY 10.14.10.176:9999";
\}

Case 3: 고위험 카테고리만 RBI 적용​

요구사항:

  • 신뢰할 수 있는 사이트(Microsoft, Google)는 DIRECT
  • 알려지지 않은 사이트만 RBI 적용

구현:

function FindProxyForURL(url, host) \{
// 신뢰 도메인 리스트
var trustedDomains = [
"microsoft.com", "google.com", "github.com",
"stackoverflow.com", "azure.com"
];

for (var i = 0; i < trustedDomains.length; i++) \{
if (dnsDomainIs(host, trustedDomains[i])) \{
return "DIRECT";
\}
\}

// 기타 사이트는 RBIProxy 경유
return "PROXY 10.14.10.176:9999";
\}

Case 4: 모니터링 및 로깅​

요구사항:

  • 실시간 트래픽 모니터링
  • 어떤 사용자가 어떤 사이트에 접속하는지 추적

구현:

# 실시간 활성 세션 모니터링
watch -n 2 'curl -s http://10.14.10.176:9999/sessions | jq .'

# 로그 파일 실시간 확인 (Kubernetes)
kubectl logs -f deployment/rbiproxy -n shieldinfo-dev

# 특정 사용자 IP 필터링
kubectl logs deployment/rbiproxy -n shieldinfo-dev | grep "192.168.1.100"

배포 아키텍처​

Kubernetes 환경​

┌────────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Namespace: shieldinfo-dev │ │
│ │ │ │
│ │ ┌──────────────────┐ ┌──────────────────┐ │ │
│ │ │ ConfigMap │───→│ Deployment │ │ │
│ │ │ rbiproxy-config │ │ │ │ │
│ │ │ │ │ ┌────────────┐ │ │ │
│ │ │ RBI_BASEURL │ │ │ rbiproxy │ │ │ │
│ │ │ RBI_LINK_TYPE │ │ │ Container │ │ │ │
│ │ │ RBIPROXY_PORT │ │ │ │ │ │ │
│ │ └──────────────────┘ │ │ Port:9999 │ │ │ │
│ │ │ └────────────┘ │ │ │
│ │ └────────┬─────────┘ │ │
│ │ │ │ │
│ │ ┌────────▼─────────┐ │ │
│ │ │ Service │ │ │
│ │ │ rbiproxy │ │ │
│ │ │ │ │ │
│ │ │ Port 80, 9999 │ │ │
│ │ └────────┬─────────┘ │ │
│ └────────────────────────────────────┼────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────▼────────────────┐ │
│ │ Namespace: kube-system │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ rke2-ingress-nginx-controller │ │ │
│ │ │ │ │ │
│ │ │ - containerPort.rbiproxy: 9999 │ │ │
│ │ │ - tcp-services ConfigMap 참조 │ │ │
│ │ └───────────────────┬──────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌───────────────────▼──────────────────────────┐ │ │
│ │ │ Service (NodePort/LoadBalancer) │ │ │
│ │ │ Port 9999 외부 노출 │ │ │
│ │ └───────────────────┬──────────────────────────┘ │ │
│ └──────────────────────┼───────────────────────────────┘ │
│ │ │
└─────────────────────────┼─────────────────────────────────────┘
│
│ NodePort or LoadBalancer
↓
┌───────────────┐
│ 외부 접속 │
│ (사용자 PC) │
└───────────────┘

고가용성 구성​

다중 Replica 배포:

spec:
replicas: 3 # 3개 인스턴스 실행
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 최대 1개까지만 동시 다운
maxSurge: 1 # 최대 1개까지 추가 생성

HPA (Horizontal Pod Autoscaler):

# CPU 사용률 기반 자동 스케일링
kubectl autoscale deployment rbiproxy \
--cpu-percent=70 \
--min=2 \
--max=10 \
-n shieldinfo-dev

환경변수​

Kubernetes ConfigMap을 통해 설정을 주입합니다.

필수 환경변수​

환경변수예시 값설명
RBIPROXY_PORT9999프록시 서비스 포트
RBI_BASEURLhttps://shieldgate.softcamp.co.krSHIELDGate 서버 주소 (끝에 / 자동 추가됨)
RBI_LINK_TYPESHIELDGate연동 방식 (SHIELDGate 또는 DIRECT)
TZAsia/Seoul타임존 (로그 시간 표시용)

선택 환경변수​

환경변수기본값설명
LOG_LEVELinfo로그 레벨 (error, warn, info, debug)
RESTAPI_JWT_SECRET_B64자동 생성JWT 서명 시크릿 (Base64)

환경변수 우선순위​

1순위: 환경변수 (ConfigMap/환경변수)
2순위: config.yaml 파일
3순위: 커맨드라인 플래그

Kubernetes 배포 시 ConfigMap의 환경변수가 최우선 적용됩니다.


성능 및 리소스​

리소스 요구사항​

환경CPU RequestCPU LimitMemory RequestMemory LimitReplicas
개발/테스트100m500m200Mi512Mi1
소규모 운영200m700m300Mi1Gi2
중규모 운영500m1000m500Mi2Gi3
대규모 운영1000m2000m1Gi3Gi5+

예상 처리량​

단일 인스턴스 기준 (리소스: 700m CPU, 1Gi Memory):

  • 동시 연결: 약 500~1,000개
  • 초당 요청: 약 100~200 req/s
  • 응답 시간: 평균 10~50ms (리다이렉트만)

실제 성능은 다음 요인에 따라 달라집니다:

  • 네트워크 대역폭
  • SHIELDGate 응답 속도
  • TLS 핸드셰이크 오버헤드

병목 지점​

  1. TLS MITM: 각 HTTPS 요청마다 핸드셰이크 필요 → CPU 사용량 증가
  2. 동적 인증서 발급: 도메인별 인증서 생성 → 메모리 사용량 증가
  3. 로깅: 모든 요청을 로깅하면 I/O 부하 증가

최적화 팁:

  • 로그 레벨을 warn 또는 error로 낮춤
  • Replica 수 증가로 부하 분산
  • SHIELDGate 서버와 같은 네트워크에 배치 (레이턴시 감소)

로깅 및 모니터링​

로그 형식​

2026-04-01 15:23:45 [INFO] Local HTTP Request - IP: 192.168.1.100:52341, URL: http://example.com, Method: GET
2026-04-01 15:23:45 [INFO] Local [GET http://example.com] code=200 OK elap=12ms

2026-04-01 15:24:10 [INFO] Local HTTPS CONNECT Request - IP: 192.168.1.100:52342, Host: secure.example.com:443
2026-04-01 15:24:10 [INFO] Local HTTPS Detail - IP: 192.168.1.100:52342, Method: GET, URL: https://secure.example.com/
2026-04-01 15:24:10 [INFO] Local [CONNECT secure.example.com:443] GET https://secure.example.com/ code=200 OK elap=45ms

로그 분류​

로그 타입설명의미
Local HTTP Request일반 브라우저의 HTTP 요청 수신사용자가 HTTP 사이트 접속 시도
Local HTTPS CONNECT일반 브라우저의 HTTPS CONNECT 요청사용자가 HTTPS 사이트 접속 시도
Local HTTPS DetailHTTPS 요청의 실제 내용TLS 복호화 후 확인된 URL

Prometheus 메트릭 (향후 추가 가능)​

# 활성 세션 수
rbiproxy_active_sessions_total

# 요청 처리 시간 (히스토그램)
rbiproxy_request_duration_seconds

# 요청 수
rbiproxy_requests_total

# 에러 발생 수
rbiproxy_errors_total\{type="tls|redirect|connection"\}

보안 고려사항​

1. 사설 인증서 관리​

위험:

  • RBIProxy의 CA 인증서가 유출되면 MITM 공격 가능
  • 인증서 유효기간 만료 시 서비스 중단

대응:

  • CA 인증서 파일(proxy_cert.pem, proxy_pkey.pem)을 안전하게 보관
  • Kubernetes Secret으로 관리 (ConfigMap 대신)
  • 주기적인 인증서 갱신 (예: 1년마다)

인증서 재생성:

openssl req -x509 -newkey rsa:4096 \
-keyout proxy_pkey.pem \
-out proxy_cert.pem \
-sha256 -days 3650 -nodes \
-subj "/C=KR/ST=Seoul/O=Security365/CN=RBIProxy" \
-addext "subjectAltName=DNS:RBIProxy"

2. REST API 접근 제어​

위험:

  • /sessions API로 사용자 트래픽 노출 가능

대응:

  • Basic Auth 설정 필수
  • localhost 외부 접속 시 인증 강제
  • Kubernetes NetworkPolicy로 API 접근 제한

Basic Auth 설정 (config.yaml):

restapi:
basicAuth:
username: admin
password: strong_password_here

3. 무한 루프 방지​

위험:

  • PAC 파일에서 SHIELDGate를 DIRECT로 처리하지 않으면 무한 루프 발생

대응:

// PAC 파일에 반드시 포함
if (dnsDomainIs(host, "shieldgate.softcamp.co.kr")) \{
return "DIRECT"; // 프록시 우회
\}

4. 내부 네트워크 격리​

권장 구성:

DMZ:        [RBIProxy] ← 사용자 PC 접근
Internal: [SHIELDGate] ← RBIProxy만 접근 가능

NetworkPolicy 예시:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: rbiproxy-policy
spec:
podSelector:
matchLabels:
app: rbiproxy
ingress:
- from:
- namespaceSelector:
matchLabels:
name: dmz
ports:
- protocol: TCP
port: 9999

고급 설정​

1. 다중 RBI 서버 지원​

시나리오: 부서별로 다른 RBI 서버 사용

구현 방법:

  • RBIProxy를 여러 개 배포 (각각 다른 RBI_BASEURL 설정)
  • PAC 파일에서 IP 대역별로 다른 프록시 지정
function FindProxyForURL(url, host) \{
var clientIP = myIpAddress();

// 개발팀 (10.14.20.0/24) → RBIProxy-Dev
if (isInNet(clientIP, "10.14.20.0", "255.255.255.0")) \{
return "PROXY 10.14.10.100:9999";
\}

// 일반 부서 → RBIProxy-Prod
return "PROXY 10.14.10.176:9999";
\}

2. 화이트리스트 중앙 관리​

현재: PAC 파일에 예외 도메인을 하드코딩

개선 방안:

  • 중앙 관리 시스템(DB, Redis 등)에서 예외 도메인 목록 관리
  • RBIProxy가 동적으로 로드
  • PAC 파일을 템플릿으로 생성

3. 지역별 RBI 서버 분산​

시나리오: 지사별로 가까운 RBI 서버 사용

function FindProxyForURL(url, host) \{
var clientIP = myIpAddress();

// 서울 본사 (10.14.0.0/16)
if (isInNet(clientIP, "10.14.0.0", "255.255.0.0")) \{
return "PROXY 10.14.10.176:9999"; // 서울 RBIProxy
\}

// 부산 지사 (10.20.0.0/16)
if (isInNet(clientIP, "10.20.0.0", "255.255.0.0")) \{
return "PROXY 10.20.10.50:9999"; // 부산 RBIProxy
\}

return "DIRECT";
\}

FAQ (자주 묻는 질문)​

Q1: RBIProxy가 다운되면 인터넷이 안되나요?​

A: 예. 프록시가 다운되면 모든 웹 접속이 불가능합니다.

대응 방안:

  • 고가용성 구성: 다중 Replica 배포 (최소 2개)

  • Failover: PAC 파일에 백업 프록시 지정

    // 메인 프록시 실패 시 백업 프록시 사용
    return "PROXY 10.14.10.176:9999; PROXY 10.14.10.177:9999; DIRECT";
  • 모니터링: Prometheus + Grafana로 실시간 상태 확인

  • 알람: Alertmanager로 다운 시 즉시 알림

Q2: 특정 사용자만 RBI를 적용할 수 있나요?​

A: 예. PAC 파일에서 IP 대역 또는 사용자별 분기가 가능합니다.

function FindProxyForURL(url, host) \{
var clientIP = myIpAddress();

// VIP/임원진은 DIRECT 접속 허용
if (isInNet(clientIP, "10.14.1.0", "255.255.255.0")) \{
return "DIRECT";
\}

// 일반 직원은 RBIProxy 경유
return "PROXY 10.14.10.176:9999";
\}

Q6: 로그에서 어떤 정보를 확인할 수 있나요?​

A: 다음 정보를 로깅합니다:

  • 클라이언트 IP 주소
  • 요청 URL 및 Method
  • 응답 시간
  • HTTP 상태 코드

개인정보 보호:

  • POST 바디는 로깅하지 않음
  • 쿠키, Authorization 헤더는 로깅하지 않음
  • URL의 쿼리 파라미터는 로깅됨 (민감 정보 포함 가능)

제한사항 및 알려진 이슈​

1. WebSocket 지원 제한​

현상: WebSocket 연결이 정상 동작하지 않을 수 있음

원인: HTTP Upgrade 요청 처리 미지원

해결: WebSocket을 사용하는 사이트는 PAC 예외 처리

// WebSocket 사용 사이트 예외
if (dnsDomainIs(host, "slack.com") ||
dnsDomainIs(host, "teams.microsoft.com")) \{
return "DIRECT";
\}

2. 일부 인증 방식 호환성 문제​

현상: 클라이언트 인증서 기반 사이트 접속 불가

원인: MITM 과정에서 클라이언트 인증서가 전달되지 않음

해결: 해당 사이트를 PAC 예외 처리

3. HTTP/2 및 HTTP/3​

현재 상태: HTTP/1.1만 완전 지원

HTTP/2: goproxy 라이브러리 제약으로 제한적 지원

HTTP/3: 미지원 (QUIC 프로토콜)


관련 문서​

설치 및 운영​

  • [구축 가이드](../../내부 문서/구축-설치-운영 가이드/RBI Proxy/RBIProxy 구축 가이드.md): Kubernetes 배포 전체 절차
  • [환경변수](../../내부 문서/구축-설치-운영 가이드/RBI Proxy/RBIProxy config.js 가이드.md): ConfigMap 설정 상세
  • main.go 코드 분석: 내부 동작 원리

REST API​

프로젝트 정보​

  • README.md: 프로젝트 개요 및 변경 이력

라이선스 및 오픈소스​

사용 중인 오픈소스​

라이브러리라이선스용도
elazarl/goproxyBSD-3-ClauseHTTP/HTTPS 프록시 엔진
spf13/viperMIT설정 파일 관리

변경 이력​

RBIProxy는 원래 lqqyt2423/go-mitmproxy를 기반으로 했으나, elazarl/goproxy로 변경되었습니다 (v1.0.0.1, 2024-06-11).

변경 이유:

  • 더 나은 HTTPS 처리
  • 안정적인 MITM 기능
  • 활발한 커뮤니티 지원

요약​

RBIProxy는:

  • 사용자 PC와 인터넷 사이의 투명한 보안 계층
  • Windows PAC를 통해 자동으로 적용되는 프록시
  • SOFTCAMP SHIELDGate와 연동하여 웹 접속을 격리 환경으로 전환
  • PAC 파일을 통한 선별적 필터링으로 무한 루프 방지
  • Kubernetes에서 손쉽게 배포 및 확장 가능

한 줄 요약:
"PAC 필터링을 통과한 트래픽을 SHIELDGate로 변환하는 URL 변환 프록시"


다음 단계​

  1. [구축 가이드](../../내부 문서/구축-설치-운영 가이드/RBI Proxy/RBIProxy 구축 가이드.md)를 참고하여 배포
  2. PAC 파일을 환경에 맞게 커스터마이징
  3. 사용자 PC에 CA 인증서 설치
  4. Windows GPO로 PAC 설정 일괄 배포
  5. 모니터링 대시보드 구축 (/sessions API 활용)

문의:

  • 기술 지원: SOFTCAMP
  • 프로젝트 관리: nicejh

최종 수정: 2026-04-01